package jp.co.dailyReport.project.action;

import java.io.IOException;
import java.util.Vector;
import java.util.Calendar;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.validator.DynaValidatorForm;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import jp.co.dailyReport.DataUnavailableException;
import jp.co.dailyReport.PermissionException;
import jp.co.dailyReport.project.PjStaff;
import jp.co.dailyReport.project.PjStaffManager;
import jp.co.dailyReport.project.Project;
import jp.co.dailyReport.project.ProjectManager;
import jp.co.dailyReport.staff.Staff;
import jp.co.dailyReport.staff.StaffManager;
import jp.co.dailyReport.workItem.WorkItem;
import jp.co.dailyReport.workItem.WorkItemManager;
import jp.co.dailyReport.customer.Customer;
import jp.co.dailyReport.customer.CustomerManager;
import jp.co.dailyReport.Utilities;
import jp.co.dailyReport.SystemCalendar;

/**
 * ﾌﾟﾛｼﾞｪｸﾄ情報編集ページのボタン（戻る、確定、追加(作業項目)、削除(作業項目)、<BR>
 * 追加(プロジェクトメンバー)、削除(プロジェクトメンバー)、↑、↓）<BR>
 * が押されたときの処理を管理するクラスです。
 */
public class ProjectEditAction extends Action {

	private static Logger log = Logger.getLogger(ProjectEditAction.class);

	/**
	 * ﾌﾟﾛｼﾞｪｸﾄ情報編集ページで押されるボタン（戻る、更新、追加(作業項目)、削除(作業項目)、<BR>
	 * 追加(プロジェクトメンバー)、削除(プロジェクトメンバー)、↑、↓）<BR>
	 * によって、実行する処理を制御します。<BR><BR>
	 * 
	 * 「戻る」ボタンが押された場合の処理：<BR>
	 * プロジェクト情報、取引先情報、社員情報を取得します。<BR><BR>
	 * 「更新」ボタンが押された場合の処理：<BR>
	 * プロジェクトIDからプロジェクト情報を取得します。<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * 入力チェックを行います。<BR>
	 * プロジェクト情報、作業項目情報、プロジェクト参加メンバー情報をDBから更新します。<BR><BR>
	 * 「追加」ボタン(プロジェクトメンバー)が押された場合の処理：<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * 追加されたプロジェクトメンバーの社員IDから社員情報を取得し、Staffオブジェクトを<BR>
	 * セッションに設定します。<BR><BR>
	 * 「削除」ボタン(プロジェクトメンバー)が押された場合の処理：<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * 削除されなかったプロジェクトメンバーの社員IDから社員情報を取得し、Staffオブジェクトを<BR>
	 * セッションに設定します。<BR><BR>
	 * 「追加」ボタン(作業項目)が押された場合の処理：<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * 入力チェックを行います。<BR>
	 * WorkItemインスタンスを生成し、追加された作業項目情報をセットし、セッションに設定します。<BR>
	 * 「削除」ボタン(作業項目)が押された場合の処理：<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * セッションから作業項目情報を取得して、削除されなかったWorkItemオブジェクトをセッションに設定します。<BR><BR>
	 * 「↑」ボタンが押された場合の処理：<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * セッションから作業項目情報を取得して、選択されたWorkItemオブジェクトの表示順位と<BR>
	 * それより1大きい表示順位のWorkItemオブジェクトをいれかえてセッションに設定します。<BR><BR>
	 * 「↓」ボタンが押された場合の処理：<BR>
	 * 取引先情報、社員情報を取得します。<BR>
	 * セッションから作業項目情報を取得して、選択されたWorkItemオブジェクトの表示順位と<BR>
	 * それより1小さい表示順位のWorkItemオブジェクトをいれかえてセッションに設定します。
	 * 
	 * @param mapping このインスタンスを選択するために使用したActionMapping
	 * @param form 存在するならば、このリクエストのためのActionForm Bean
	 * @param request 処理しているHTTPリクエスト
	 * @param response 処理しているHTTPレスポンス
	 * @return ActionForwardインスタンス
	 * @throws IOException, ServletException
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
	 throws IOException, ServletException {

		log.debug("ProjectEditAction start");
		HttpSession session = request.getSession();
		log.debug("session.getId() = " + session.getId());
		String target = null;
		ActionErrors errors = new ActionErrors();

		pjCommon(form, request);

		if(request.getParameter("edit") != null) {
			DynaValidatorForm doProjectActionForm = (DynaValidatorForm)form;
			if ((String)doProjectActionForm.get("name") == null || ((String)doProjectActionForm.get("name")).length() == 0){
				errors.add("name",new ActionError("errors.name.required"));
			}
			if (!errors.isEmpty()){
				target = "reTryEdit";
				saveErrors(request,errors);
			}else{
				target = "edit";
				projectEdit(form, request);
			}
		} else if(request.getParameter("returnList") != null) {
			target = "returnList";
			projectReturnList(form, request);

		} else if(request.getParameter("pjStaffAdd") != null) {
			target = "pjStaffAdd";
			pjStaffAdd(form, request);

		} else if(request.getParameter("pjStaffRm") != null) {
			target = "pjStaffRm";
			pjStaffRm(form, request);

		} else if(request.getParameter("workItemAdd") != null) {
			DynaValidatorForm doProjectActionForm = (DynaValidatorForm)form;
			String workItemName = ((String)doProjectActionForm.get("workItemName")).trim();
			if (workItemName == null || workItemName.length() == 0){
				errors.add("workItemName",new ActionError("errors.workItemName.required"));
			}
			if (!errors.isEmpty()){
				target = "reTryEdit";
				saveErrors(request,errors);
			}else{
				target = "workItemAdd";
				pjWorkItemAdd(form, request);
			}
		} else if(request.getParameter("workItemRm") != null) {
			target = "workItemRm";
			pjWorkItemRm(form, request);
		}

		Vector pjWorkItemList = (Vector)session.getAttribute("pjWorkItemList");
		WorkItem[] workItem = (WorkItem[])pjWorkItemList.toArray(new WorkItem[0]);
		for(int i=0;i<workItem.length;i++){
			if(request.getParameter("workItemUp[" + i + "]") != null) {
				target = "workItemUp";
				workItemUp(request,i);
			} else if(request.getParameter("workItemDown[" + i + "]") != null) {
				target = "workItemDown";
				workItemDown(request,i);
			}
		}

		log.debug("ProjectEditAction end");
		return mapping.findForward(target);
	}

	private void pjCommon(ActionForm form, HttpServletRequest request) {

		Customer[] customerList = null;
		Staff[] staffList = null;

		try {
			customerList = CustomerManager.load();
			staffList = StaffManager.load();
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
		request.setAttribute("customerList", customerList);
		request.setAttribute("staffList", staffList);
		request.setAttribute("staff", new Staff());
		request.setAttribute("systemCalendar", new SystemCalendar());
	}

	private void projectEdit(ActionForm form, HttpServletRequest request) {

		HttpSession session = request.getSession();
		Staff staff = (Staff)session.getAttribute("LoginStaff");
		Vector pjStaffList = (Vector)session.getAttribute("pjStaffList");
		Vector pjWorkItemList = (Vector)session.getAttribute("pjWorkItemList");
		Staff[] staffs = (Staff[])pjStaffList.toArray(new Staff[0]);
		WorkItem[] workItems = (WorkItem[])pjWorkItemList.toArray(new WorkItem[0]);

		Vector rmPjStaffList = (Vector)session.getAttribute("rmPjStaffList");
		Vector rmPjWorkItemList = (Vector)session.getAttribute("rmPjWorkItemList");
		PjStaff[] rmStaffs = (PjStaff[])rmPjStaffList.toArray(new PjStaff[0]);
		WorkItem[] rmWorkItems = (WorkItem[])rmPjWorkItemList.toArray(new WorkItem[0]);

		DynaValidatorForm doProjectActionForm = (DynaValidatorForm)form;
		int projectId = ((Integer)doProjectActionForm.get("projectId")).intValue();
		Project project = new Project();

		Calendar periodStart = Utilities.getCalendarTime(
		((Integer)doProjectActionForm.get("periodStartY")).intValue(),
		((Integer)doProjectActionForm.get("periodStartM")).intValue(),
		((Integer)doProjectActionForm.get("periodStartD")).intValue(),
		0,0);

		Calendar periodEnd = Utilities.getCalendarTime(
		((Integer)doProjectActionForm.get("periodEndY")).intValue(),
		((Integer)doProjectActionForm.get("periodEndM")).intValue(),
		((Integer)doProjectActionForm.get("periodEndD")).intValue(),
		0,0);

		project.setPeriodStart(periodStart);
		project.setPeriodEnd(periodEnd);
		project.setProjectId(projectId);
		project.setCustomerId(((Integer)doProjectActionForm.get("customerId")).intValue());
		project.setName((String)doProjectActionForm.get("name"));
		project.setOutline((String)doProjectActionForm.get("outline"));
		project.setPjCustomerStaff((String)doProjectActionForm.get("pjCustomerStaff"));
		project.setPLStaffId(((Integer)doProjectActionForm.get("pLStaffId")).intValue());
		Boolean statusFlg = new Boolean((String)doProjectActionForm.get("statusFlg"));
		project.setStatusFlg(statusFlg.booleanValue());

		try{
			/* プロジェクトテーブルのデータ更新 */
			ProjectManager.update(staff,project);
			/* プロジェクト参加社員テーブルのデータ挿入 */
			for(int i=0;i<staffs.length;i++){
				if(!PjStaffManager.isExist(projectId,staffs[i].getStaffId())){
					PjStaff pjStaff = new PjStaff();
					pjStaff.setProjectId(projectId);
					pjStaff.setStaffId(staffs[i].getStaffId());
					PjStaffManager.insert(pjStaff);
				}
			}
			/* 作業項目テーブルのデータ挿入 */
			for(int i=0;i<workItems.length;i++){
				if(workItems[i].getWorkItemId()==0){
					workItems[i].setProjectId(projectId);
					WorkItemManager.insert(workItems[i]);
				} else {
					WorkItemManager.update(workItems[i]);
				}
			}
			/* プロジェクト参加社員テーブルのデータ削除 */
			for(int i=0;i<rmStaffs.length;i++){
				int count = 0;
				for(int j=0;j<staffs.length;j++){
					if(rmStaffs[i].getStaffId()==staffs[j].getStaffId()) {
						count++;
					}
				}
				if(count<=0){
					PjStaffManager.delete(projectId,rmStaffs[i].getStaffId());
				}
			}
			/* 作業項目テーブルのデータ削除 */
			for(int i=0;i<rmWorkItems.length;i++){
				int count = 0;
				for(int j=0;j<workItems.length;j++){
					if(rmWorkItems[i].getWorkItemId()==workItems[j].getWorkItemId()) {
						count++;
					}
				}
				if(count<=0){
					log.debug("staffId = " + staff.getStaffId() + " workItemId = " + rmWorkItems[i].getWorkItemId());
					WorkItemManager.delete(rmWorkItems[i].getWorkItemId());
				}
			}
		} catch(PermissionException e) {
			log.error(e.toString());
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
	}

	private void projectReturnList(ActionForm form, HttpServletRequest request) {

		HttpSession session = request.getSession();
		Staff staff = (Staff)session.getAttribute("LoginStaff");
		session.removeAttribute("pjStaffList");
		session.removeAttribute("rmPjStaffList");
		Project[] projectList = null;

		try {
			projectList = ProjectManager.load(staff);
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
		request.setAttribute("projectList", projectList);
	}

	private void pjStaffAdd(ActionForm form, HttpServletRequest request) {

		HttpSession session = request.getSession();
		Vector pjStaffList = (Vector)session.getAttribute("pjStaffList");

		if(pjStaffList.size()==0){
			pjStaffList = new Vector();
		}

		try {
			pjStaffList.add(StaffManager.load(Integer.parseInt(request.getParameter("staffId"))));
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
		session.setAttribute("pjStaffList", pjStaffList);
	}

	private void pjStaffRm(ActionForm form, HttpServletRequest request) {

		HttpSession session = request.getSession();
		Vector beforePjStaffList = (Vector)session.getAttribute("pjStaffList");
		Vector afterPjStaffList = new Vector();
		Staff[] staff = (Staff[])beforePjStaffList.toArray(new Staff[0]);

		for(int i=0;i<staff.length;i++){
			if(request.getParameter("pjStaffList[" + i + "].staffId")==null){
				afterPjStaffList.add(staff[i]);
			}
		}
		session.setAttribute("pjStaffList", afterPjStaffList);
	}

	private void pjWorkItemAdd(ActionForm form, HttpServletRequest request) {

		HttpSession session = request.getSession();
		Vector pjWorkItemList = (Vector)session.getAttribute("pjWorkItemList");
		DynaValidatorForm doProjectActionForm = (DynaValidatorForm)form;

		if(pjWorkItemList.size()==0){
			pjWorkItemList = new Vector();
		}

		int i = pjWorkItemList.size();

		WorkItem workItem = new WorkItem();
		workItem.setName((String)doProjectActionForm.get("workItemName"));
		workItem.setDisplayNm(i);
		pjWorkItemList.add(workItem);
		session.setAttribute("pjWorkItemList", pjWorkItemList);

	}

	private void pjWorkItemRm(ActionForm form, HttpServletRequest request) {

		HttpSession session = request.getSession();
		Vector beforePjWorkItemList = (Vector)session.getAttribute("pjWorkItemList");
		Vector afterPjWorkItemList = new Vector();
		WorkItem[] workItem = (WorkItem[])beforePjWorkItemList.toArray(new WorkItem[0]);
		int j = 0;

		for(int i=0;i<workItem.length;i++){
			if(request.getParameter("pjWorkItemList[" + i + "].displayNm")==null) {
				workItem[i].setDisplayNm(j);
				afterPjWorkItemList.add(workItem[i]);
				j++;
			}
		}
		session.setAttribute("pjWorkItemList", afterPjWorkItemList);
	}

	private void workItemUp(HttpServletRequest request, int displayNm) {

		HttpSession session = request.getSession();
		Vector pjWorkItemList = (Vector)session.getAttribute("pjWorkItemList");
		try {
			pjWorkItemList = WorkItemManager.getUpWorkItem(displayNm,pjWorkItemList);
			session.setAttribute("pjWorkItemList", pjWorkItemList);
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
	}

	private void workItemDown(HttpServletRequest request, int displayNm) {

		HttpSession session = request.getSession();
		Vector pjWorkItemList = (Vector)session.getAttribute("pjWorkItemList");

		try {
			pjWorkItemList = WorkItemManager.getDownWorkItem(displayNm,pjWorkItemList);
			session.setAttribute("pjWorkItemList", pjWorkItemList);
		} catch(DataUnavailableException due) {
			log.error(due.getMessage());
		}
	}
}
